package com.hook.project;

import android.content.Context;
import android.os.Build;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.hook.tools.IOUtils;
import com.hook.tools.MyThreadLocal;
import com.hook.tools.initXposedHook;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.KeyPair;
import java.util.HashMap;
import java.util.Map;

import de.robv.android.xposed.XposedHelpers;
import fi.iki.elonen.NanoHTTPD;

import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;

public class MeiTuanServer {

    /**
     * 美团流程处理
     *
     * @param parameters
     * @return
     * @throws Exception
     */
    public static NanoHTTPD.Response getSecret(Map<String, String> parameters) throws Exception {
        String method = parameters.get("method");
        String str = "{msg:\"未知方法名称\"}";
        //获取当前定位下的美食分类数据 接口实现类 API 对象
        Object meituanApiClassObject = initXposedHook.meituanApiClassObject;
        //获得超市便利等下的分类接口的实现类对象 SCApi 对象
        Object meituanSCApiClassObject = initXposedHook.meituanSCApiClassObject;
        MyThreadLocal.getInstance().set("getData");
        if (method.equals("category")) {
            try {
                Method m = meituanApiClassObject.getClass().getDeclaredMethod("getHomeNewRcmdboard",
                        int.class,
                        String.class,
                        String.class,
                        String.class,
                        String.class,
                        String.class,
                        String.class,
                        int.class,
                        String.class);
                //获取返回结果对象,res.a.call 反射调用 请求就发出去了
                Object res = m.invoke(meituanApiClassObject, 0, "", "", null, null, null, "", 0, "");
                //获取参数2 回调函数, 返回的数据会在 rx_jObject 下的onNext的回调函数中传入
                Object rx_jObject = initXposedHook.rx_jObject;
                Field d = res.getClass().getDeclaredField("a");
                d.setAccessible(true);
                Object a = d.get(res);
                Method m1 = a.getClass().getDeclaredMethod("call", XposedHelpers.findClass("rx.j", initXposedHook.classLoader));
                m1.setAccessible(true);
                m1.invoke(a, rx_jObject);
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getName());
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getMethods().length);
                str = MyThreadLocal.getInstance().get();
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("EDXposed", e.getMessage());
            }
            Log.e("EDXposed", "----====----====----====----====----====----====----====----");
        }
        else if (method.equals("sonCategory")) {
            String categoryId = parameters.get("categoryId");
            try {
                Method m = meituanSCApiClassObject.getClass().getDeclaredMethod("getQuickBuyHomeNew",
                        String.class,
                        String.class,
                        long.class,
                        String.class,
                        String.class,
                        String.class,
                        String.class);
                //获取返回结果对象,res.a.call 反射调用 请求就发出去了
                Object res = m.invoke(meituanSCApiClassObject, categoryId, "0", 0, "", "", null, "");
                //获取参数2 回调函数, 返回的数据会在 rx_jObject 下的onNext的回调函数中传入
                Object rx_jObject = initXposedHook.rx_jObject;
                Field d = res.getClass().getDeclaredField("a");
                d.setAccessible(true);
                Object a = d.get(res);
                Method m1 = a.getClass().getDeclaredMethod("call", XposedHelpers.findClass("rx.j", initXposedHook.classLoader));
                m1.setAccessible(true);
                m1.invoke(a, rx_jObject);
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getName());
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getMethods().length);
                str = MyThreadLocal.getInstance().get();
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("EDXposed", e.getMessage());
            }
            Log.e("EDXposed", "----====----====----====----====----====----====----====----");
        }else if (method.equals("shopListCategory")) {
            //获取附近的店铺列表数据
            String categoryType = parameters.get("categoryType");
            String page = parameters.get("page");
            try {
                Method m = meituanSCApiClassObject.getClass().getDeclaredMethod("getPoiVerticalitylistNew",
                        long.class,
                        String.class,
                        long.class,
                        int.class,
                        long.class,
                        long.class,
                        String.class,
                        String.class,
                        String.class,
                        int.class,
                        String.class,
                        String.class,
                        String.class,
                        int.class,
                        int.class,
                        int.class);
                //获取返回结果对象,res.a.call 反射调用 请求就发出去了
                /**
                 * @Field("category_type") long j          参数值:102603
                 * @Field("second_category_type") String str          参数值:0 默认值
                 * @Field("page_index") long j2          参数值:0
                 * @Field("page_size") int i          参数值:20
                 * @Field("navigate_type") long j3          参数值:102603
                 * @Field("sort_type") long j4          参数值:0 参数  排序 1为销量排序，2为配送速度排序
                 * @Field("rank_trace_id") String str2          参数值:null
                 * @Field("session_id") String str3          参数值:4386694b-6fbe-4f8a-8b79-9054707d00481606627897162354
                 * @Field("union_id") String str4          参数值:c872330147a049b1b4dd7289d5bfe0b6a160616579659223891
                 * @Field("is_home_page") int i2          参数值:0
                 * @Field("activity_filter_codes") String str5          参数值:null
                 * @Field("pageSource") String str6          参数值:sg_homepage
                 * @Field("spu_filter_codes") String str7          参数值:null
                 * @Field("template_code") int i3          参数值:0
                 * @Field("request_type") int i4          参数值:0
                 * @Field("is_partial_refresh") int i5          参数值:0
                 */
                Object res = m.invoke(meituanSCApiClassObject,
                        Long.valueOf(categoryType), "0", Long.valueOf(page) - 1, 20,
                        Long.valueOf(categoryType), 0,
                        null, "", "", 1, null, "sg_homepage", null, 0, 0, 0);
                //获取参数2 回调函数, 返回的数据会在 rx_jObject 下的onNext的回调函数中传入
                Object rx_jObject = initXposedHook.rx_jObject;
                Field d = res.getClass().getDeclaredField("a");
                d.setAccessible(true);
                Object a = d.get(res);
                Method m1 = a.getClass().getDeclaredMethod("call", XposedHelpers.findClass("rx.j", initXposedHook.classLoader));
                m1.setAccessible(true);
                m1.invoke(a, rx_jObject);
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getName());
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getMethods().length);
                str = MyThreadLocal.getInstance().get();
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("EDXposed", e.getMessage());
            }
            Log.e("EDXposed", "----====----====----====----====----====----====----====----");
        }
        else if (method.equals("shopMenu")) {
            String poiId = parameters.get("poiId");
            /**
             * @Field("wm_poi_id") long j      参数1:1053887408869739
             * @Field("product_spu_id") Long l      参数2:null
             * @Field("page_index") int i      参数3:0
             * @Field("tag_id") Long l2      参数4:-1
             * @Field("extra") String str      参数5:{"source_id":"2"}
             */
            try {
                Method m = meituanSCApiClassObject.getClass().getDeclaredMethod("getShopMenu",
                        long.class,
                        Long.class,
                        int.class,
                        Long.class,
                        String.class);
                Object res = m.invoke(meituanSCApiClassObject,
                        Long.valueOf(poiId), null, 0, -1L,
                        "{\"source_id\":\"1\"}");
                //获取参数2 回调函数, 返回的数据会在 rx_jObject 下的onNext的回调函数中传入
                Object rx_jObject = initXposedHook.rx_jObject;
                Field d = res.getClass().getDeclaredField("a");
                d.setAccessible(true);
                Object a = d.get(res);
                Method m1 = a.getClass().getDeclaredMethod("call", XposedHelpers.findClass("rx.j", initXposedHook.classLoader));
                m1.setAccessible(true);
                m1.invoke(a, rx_jObject);
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getName());
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getMethods().length);
                str = MyThreadLocal.getInstance().get();
            } catch (Exception e) {
                Log.e("EDXposed", e.getMessage());
                e.printStackTrace();
            }
        }
        else if (method.equals("getProducts")) {
            String poiId = parameters.get("poiId");
            String tagCode = parameters.get("tagCode");
            String pageNum = parameters.get("pageNum");
            String tagType = parameters.get("tagType");
            /**
             * @Field("page_index") int i                 参数1:0
             * @Field("spu_tag_id") String str            参数2:act_17_17
             * @Field("wm_poi_id") String str2            参数3:1053887408935275
             * @Field("tag_type") int i2                  参数4:2
             * @Field("sort_type") int i3                 参数5:1
             * @Field("is_support_smooth_render") int i4  参数6:1
             * @Field("product_spu_id") long j            参数7:-1
             * @Field("brand_ids") String str3            参数8:null
             * @Field("extra") String str4                参数9:
             * @Field("smooth_render_type") String str5   参数10:0
             */
            try {
                Method m = meituanSCApiClassObject.getClass().getDeclaredMethod("getProducts",
                        int.class,
                        String.class,
                        String.class,
                        int.class,
                        int.class,
                        int.class,
                        long.class,
                        String.class,
                        String.class,
                        String.class);
                Object res = m.invoke(meituanSCApiClassObject,
                        Integer.valueOf(pageNum) - 1, tagCode, poiId, Integer.valueOf(tagType),
                        1, 1, -1L, null, "", "0");
                //获取参数2 回调函数, 返回的数据会在 rx_jObject 下的onNext的回调函数中传入
                Object rx_jObject = initXposedHook.rx_jObject;
                Field d = res.getClass().getDeclaredField("a");
                d.setAccessible(true);
                Object a = d.get(res);
                Method m1 = a.getClass().getDeclaredMethod("call", XposedHelpers.findClass("rx.j", initXposedHook.classLoader));
                m1.setAccessible(true);
                m1.invoke(a, rx_jObject);
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getName());
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getMethods().length);
                str = MyThreadLocal.getInstance().get();
            } catch (Exception e) {
                Log.e("EDXposed", e.getMessage());
                e.printStackTrace();
            }
        }
        else if(method.equals("getProductsByIds")){
            String poiId = parameters.get("poiId");
            String tagCode = parameters.get("tagCode");
            String tagType = parameters.get("tagType");
            String spuIds = parameters.get("spuIds");
            String traceId = parameters.get("traceId");
            /**
             * @Field("wm_poi_id") String strd             参数1: poiId
             * @Field("spu_tag_id") String str2d           参数2: spu_tag_id
             * @Field("tag_type") int id                   参数3: tag_type
             * @Field("spuIds") String str3d               参数4: spuIds
             * @Field("trace_id") String str4              参数5: trace_id
             */
            try {
                java.lang.reflect.Method m = meituanSCApiClassObject.getClass().getDeclaredMethod("getProductsByIds",
                        String.class,
                        String.class,
                        int.class,
                        String.class,
                        String.class);
                Object res = m.invoke(meituanSCApiClassObject,poiId,tagCode,Integer.valueOf(tagType),spuIds,traceId);
                //获取参数2 回调函数, 返回的数据会在 rx_jObject 下的onNext的回调函数中传入
                Object rx_jObject = initXposedHook.rx_jObject;
                Field d = res.getClass().getDeclaredField("a");
                d.setAccessible(true);
                Object a = d.get(res);
                java.lang.reflect.Method m1 = a.getClass().getDeclaredMethod("call", XposedHelpers.findClass("rx.j", initXposedHook.classLoader));
                m1.setAccessible(true);
                m1.invoke(a, rx_jObject);
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getName());
                Log.e("EDXposed", "反射调用函数返回值为:" + rx_jObject.getClass().getMethods().length);
                str = MyThreadLocal.getInstance().get();
            } catch (Exception e) {
                Log.e("EDXposed", e.getMessage());
                e.printStackTrace();
            }
        }
        else if(method.equals("searchShopGoods")){
            Method m = initXposedHook.postFormRequestObject.getClass().getDeclaredMethod("postFormRequest",Map.class,String.class,Map.class,Map.class);
            String poiId = parameters.get("poiId");
            String keyword = parameters.get("keyword");
            String page_size = parameters.get("pageSize");
            String uri = "v2/search/inshop/products";
            String page_index = String.valueOf(Integer.parseInt(parameters.get("pageIndex"))-1);
            Map<String,String> map1 = new HashMap<String,String>();
            map1.put("Cat_Extra","");
            Map<String,Object> map2 = new HashMap<String,Object>();
            map2.put("cn_pt","RN");
            Map<String,Object> map3 = new HashMap<String,Object>();
            map3.put("sort_type","1");//1销量排序 默认排序
            map3.put("poisearch_global_id", "-999");
            map3.put("page_index",page_index);
            map3.put("tag_id","");
            map3.put("filter_types","");
            map3.put("keyword",keyword);
            map3.put("wmPoiId",poiId);
            map3.put("page_size",page_size);
            Object res = m.invoke(initXposedHook.postFormRequestObject,map1,uri,map2,map3);
            m = res.getClass().getDeclaredMethod("execute");
            res = m.invoke(res);
            m = res.getClass().getDeclaredMethod("body");
            for(Method mm : res.getClass().getDeclaredMethods()){
                Log.e("EDXposed","1:" + mm.getName());
            }
            res = m.invoke(res);
            for(Method mm : res.getClass().getMethods()){
                Log.e("EDXposed","2:" + mm.getName());
            }
            m = res.getClass().getMethod("toString");
            str = (String)m.invoke(res);
        }
        else {
            str = "{msg:\"未知方法名称,结束~\"}";
        }
        return newFixedLengthResponse(NanoHTTPD.Response.Status.OK, "application/json", str);
    }

    /**
     * 将map转换成url
     *
     * @param map
     * @return
     */
    public static String getUrlParamsByMap(Map<String, String> map) {
        if (map == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            sb.append(entry.getKey() + "=" + entry.getValue());
            sb.append("&");
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = s.substring(0, s.length() - 1);
        }
        return s;
    }
}
